// #include "los_hwi.h" // LiteOS 中的中断处理头文件
// #include "hi_gpio.h" // LiteOS 中的GPIO操作头文件
#include "iot_gpio.h"
#include "cmsis_os2.h"
#include "dht11.h"
// 假设已经定义好与DHT11连接的GPIO端口号

void delay_ms(unsigned int ms)
{
    unsigned int msPerTick = 1000 / osKernelGetTickFreq(); // 10ms
    if (ms >= msPerTick) {
        osDelay(ms / msPerTick);
    }

    unsigned int restMs = ms % msPerTick;
    if (restMs > 0) {
        usleep(restMs * 1000);
    }
}
// 初始化DHT11相关的GPIO
void DHT11_GPIO_Init(unsigned int DHT11_DATA_PIN)
{
    IoTGpioInit(DHT11_DATA_PIN); // 初始化GPIO
    IoTGpioSetDir(DHT11_DATA_PIN, IOT_GPIO_DIR_OUT); // 设置为输出模式
    // 可能还需要配置其他GPIO参数，例如上下拉模式等
}

// 向DHT11发送启动信号
void DHT11_SendStartSignal(unsigned int DHT11_DATA_PIN)
{
    IoTGpioSetOutputVal(DHT11_DATA_PIN, 0); // 拉低至少18ms
    hi_udelay(20000);//拉低至少18ms
    IoTGpioSetOutputVal(DHT11_DATA_PIN, 1); // 拉高约20-40us
    hi_udelay(35);     	//主机拉高20~40us
}

// 读取DHT11返回的数据
unsigned char DHT11_ReadBit(unsigned int DHT11_DATA_PIN)
{
    // unsigned char bit = 0;
    // IoTGpioSetDir(DHT11_DATA_PIN, IOT_GPIO_DIR_IN); // 设置为输入模式
    // usleep(30); // 等待DHT11拉低或拉高数据线
    // IotGpioValue v;
    // IoTGpioGetInputVal(DHT11_DATA_PIN,&v);
    // if (v == 0)
    //     bit = 1; // 如果数据线被拉低，则读到1
    // usleep(80); // 等待下一个时钟周期
    // return bit;

 	uint8_t retry=0;
    IotGpioValue v;
    IoTGpioGetInputVal(DHT11_DATA_PIN,&v);
	while(v&&retry<100){//等待变为低电平
	    retry++;
	    hi_udelay(1);
        IoTGpioGetInputVal(DHT11_DATA_PIN,&v);
	}
    retry=0;
    IoTGpioGetInputVal(DHT11_DATA_PIN,&v);
    while((!v)&&retry<100){//等待变高电平
        retry++;
        hi_udelay(1);
        IoTGpioGetInputVal(DHT11_DATA_PIN,&v);
    }
    hi_udelay(40);//等待40us	//用于判断高低电平，即数据1或0
    IoTGpioGetInputVal(DHT11_DATA_PIN,&v);
    if(v)return 1; else return 0;
}

// 读取DHT11的一字节数据
unsigned char DHT11_ReadByte(unsigned int DHT11_DATA_PIN)
{
    unsigned char byte = 0;
    for (int i = 0; i < 8; i++)
    {
        byte <<= 1;
        byte |= DHT11_ReadBit(DHT11_DATA_PIN);
    }
    return byte;
}
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
uint8_t DHT11_Check(unsigned int DHT11_DATA_PIN) 	   
{   
	uint8_t retry=0;
    IoTGpioSetDir(DHT11_DATA_PIN, IOT_GPIO_DIR_IN); // 设置为输入模式
    IotGpioValue v;
    IoTGpioGetInputVal(DHT11_DATA_PIN,&v);
    while (v&&retry<100)//DHT11会拉低40~80us
	{
		retry++;
		hi_udelay(1);
        IoTGpioGetInputVal(DHT11_DATA_PIN,&v);
	};	 
	if(retry>=100)return 1;
	else retry=0;
    IoTGpioGetInputVal(DHT11_DATA_PIN,&v);
    while ((!v)&&retry<100)//DHT11拉低后会再次拉高40~80us
	{
		retry++;
		hi_udelay(1);
        IoTGpioGetInputVal(DHT11_DATA_PIN,&v);
	};
	if(retry>=100)return 1;	   
	return 0;
}

// 读取并解析DHT11传感器数据
DHT11_Result* DHT11_ReadData(unsigned int DHT11_DATA_PIN)
{
    DHT11_GPIO_Init(DHT11_DATA_PIN);
    DHT11_SendStartSignal(DHT11_DATA_PIN);
    DHT11_Check(DHT11_DATA_PIN);
    // 接收DHT11响应的40bit数据
    unsigned char data[5] = {0};
    for (int i = 0; i < 5; i++) // 5字节数据：湿度整数、湿度小数、温度整数、温度小数、校验位
    {
        data[i] = DHT11_ReadByte(DHT11_DATA_PIN);
    }
    DHT11_Result* result = calloc(1,sizeof(DHT11_Result));
    if((data[0]+data[1]+data[2]+data[3])==data[4])//数据校验
		{
			result->humidity = data[0] + data[1] * 0.1;
			if (data[3] > 127)                                                   /* if temperature is below zero */
            {
                result->temperature = (float)(-(data[2] * 10 + data[3] & ~(1<<7))) / 10.0f;                    /* convert temperature raw data to temperature real data */
            }
            else
            {
                result->temperature = (float)(data[2]*10 + data[3]) / 10.0f;                    /* convert temperature raw data to temperature real data */
            }
		}else{
            result->temperature=-1;
            result->humidity = -1;
		}
    return result;
}
float getTemperature(DHT11_Result* result){
    return result->temperature;
}
float getHumidity(DHT11_Result* result){
    return result->humidity;
}
// int main(void)
// {
//     float temp, hum;

//     while (1)
//     {
//         DHT11_ReadData(&temp, &hum);

//         if (temp != -1.0 && hum != -1.0)
//         {
//             // 数据有效，打印或者处理温度和湿度值
//             printf("Temperature: %.1f C, Humidity: %.1f %%\n", temp, hum);
//         }
//         else
//         {
//             printf("Failed to read data from DHT11 sensor.\n");
//         }

//         // 延迟一段时间再次读取，避免过于频繁导致DHT11无法正常响应
//         delay_ms(2000);
//     }

//     return 0;
// }